<template>
  <div class="contest-detail-page">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-content">
        <button @click="goBack" class="back-btn">
          <i class="icon">←</i>
          返回比赛列表
        </button>
        <div class="header-info">
          <div class="title-section">
            <h1 class="page-title">
              <i class="icon">🏆</i>
              {{ contestData.name || contestData.title || '比赛详情' }}
            </h1>
            <div class="header-badges">
              <span class="badge type-badge" :class="getTypeClass(contestData.type)">
                {{ contestData.type }}
              </span>
              <span class="badge status-badge" :class="getStatusClass(contestData.status)">
                {{ contestData.status || '未知状态' }}
              </span>
            </div>
          </div>
          <!-- 右上角按钮组 -->
          <div class="header-actions">
            <!-- 学生不可见的按钮 -->
            <template v-if="!isStudent">
              <button @click="viewParticipants" class="header-action-btn participants-btn">
                <i class="icon">👥</i>
                选手列表
              </button>
              <button @click="viewRankings" class="header-action-btn rankings-btn" v-if="!isManagementMode">
                <i class="icon">📊</i>
                成绩表
              </button>
            </template>
            <!-- 参赛按钮（根据是否已参加显示不同状态） -->
            <template v-if="!isManagementMode">
              <button v-if="hasJoined" @click="enterExam" class="header-action-btn entered-btn">
                <i class="icon">✅</i>
                已参加 - 进入答题
              </button>
              <button v-else @click="joinContest" class="header-action-btn join-btn">
                <i class="icon">🎯</i>
                参加比赛
              </button>
            </template>
          </div>
        </div>
      </div>
    </div>

    <!-- 加载中状态 -->
    <div v-if="isLoading" class="loading-container">
      <div class="loading-spinner"></div>
      <p>正在加载比赛信息...</p>
    </div>

    <!-- 主要内容区域 -->
    <div v-else class="content-wrapper">
      <!-- 基本信息卡片 -->
      <div class="info-card">
        <div class="card-header">
          <h3><i class="icon">📋</i> 基本信息</h3>
        </div>
        <div class="card-content">
          <div class="info-grid">
            <div class="info-item">
              <label>比赛名称</label>
              <div class="info-value">{{ contestData.name || contestData.title }}</div>
            </div>
            <div class="info-item">
              <label>比赛类型</label>
              <div class="info-value">{{ contestData.type }}</div>
            </div>
            <div class="info-item full-width">
              <label>比赛描述</label>
              <div class="info-value description">{{ contestData.description || '暂无描述' }}</div>
            </div>
          </div>
        </div>
      </div>

      <!-- 时间信息卡片 -->
      <div class="info-card">
        <div class="card-header">
          <h3><i class="icon">⏰</i> 时间信息</h3>
        </div>
        <div class="card-content">
          <div class="info-grid">
            <div class="info-item">
              <label>开始时间</label>
              <div class="info-value time-value">
                <i class="icon">📅</i>
                {{ contestData.startTime }}
              </div>
            </div>
            <div class="info-item">
              <label>结束时间</label>
              <div class="info-value time-value">
                <i class="icon">📅</i>
                {{ contestData.endTime }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 参赛信息卡片 -->
      <div class="info-card">
        <div class="card-header">
          <h3><i class="icon">👥</i> 参赛信息</h3>
        </div>
        <div class="card-content">
          <div class="info-grid">
            <div class="info-item">
              <label>参赛人数</label>
              <div class="info-value">
                <span class="stat-number">{{ contestData.participantCount || contestData.registrationCount || 0 }}</span>
                人
              </div>
            </div>
            <div class="info-item">
              <label>人数限制</label>
              <div class="info-value">
                <span class="stat-number">{{ contestData.maxParticipants || '不限' }}</span>
                {{ contestData.maxParticipants ? '人' : '' }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 题目信息卡片 -->
      <div class="info-card">
        <div class="card-header">
          <h3><i class="icon">📝</i> 题目信息</h3>
          <span class="question-count">共 {{ contestData.questions?.length || 0 }} 道题</span>
        </div>
        <div class="card-content">
          <div v-if="contestData.questions && contestData.questions.length > 0" class="questions-table-wrapper">
            <table class="questions-table">
              <thead>
                <tr>
                  <th>序号</th>
                  <th>题目ID</th>
                  <th>题目名称</th>
                  <th>排序</th>
                  <th>分数</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(question, index) in contestData.questions" :key="index">
                  <td>{{ index + 1 }}</td>
                  <td>{{ question.testQuestionId || question.id }}</td>
                  <td class="title-cell">{{ question.testQuestionName || question.questionName || question.title || '未知题目' }}</td>
                  <td>{{ question.sortOrder || index + 1 }}</td>
                  <td class="score-cell">
                    <span class="score-badge">{{ question.score }} 分</span>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
          <div v-else class="no-questions">
            <i class="icon">📭</i>
            <p>暂无题目</p>
          </div>
        </div>
      </div>

      <!-- 操作按钮 -->
      <div class="action-buttons">
        <button @click="goBack" class="btn btn-secondary">
          <i class="icon">←</i>
          返回
        </button>
        <!-- 只有从比赛管理页面进入时才显示编辑按钮 -->
        <button v-if="isManagementMode" @click="editContest" class="btn btn-primary">
          <i class="icon">✏️</i>
          编辑比赛
        </button>
      </div>
    </div>

    <!-- 选手列表弹窗 -->
    <div v-if="showParticipants" class="modal-overlay" @click="closeParticipants">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h2>
            <i class="icon">👥</i>
            选手列表
          </h2>
          <button @click="closeParticipants" class="close-btn">✕</button>
        </div>
        
        <div class="modal-body">
          <div v-if="participants.length === 0" class="empty-participants">
            <i class="icon">📭</i>
            <p>暂无选手报名</p>
          </div>
          
          <div v-else class="participants-grid">
            <div v-for="participant in participants" :key="participant.id" class="participant-card">
              <div class="participant-avatar">
                <img v-if="participant.avatar" :src="participant.avatar" :alt="participant.userName || participant.name">
                <div v-else class="avatar-placeholder">
                  {{ getAvatarText(participant.userName || participant.name || participant.username) }}
                </div>
              </div>
              
              <div class="participant-info">
                <h4 class="participant-name">{{ participant.userName || participant.name || participant.username || '未知用户' }}</h4>
                <p class="participant-email">
                  <span v-if="participant.grade">{{ participant.grade }}</span>
                  <span v-else-if="participant.email">{{ participant.email }}</span>
                  <span v-else-if="participant.account">{{ participant.account }}</span>
                  <span v-else>用户ID: {{ participant.userId }}</span>
                </p>
                <div class="participant-meta">
                  <span class="meta-tag" v-if="participant.registerTime">报名时间: {{ formatDate(participant.registerTime) }}</span>
                  <span class="meta-tag" v-else-if="participant.createTime">注册时间: {{ formatDate(participant.createTime) }}</span>
                  <span class="meta-tag" v-if="participant.status !== undefined">状态: {{ participant.status === 1 ? '正常' : '其他' }}</span>
                </div>
              </div>
              
              <button @click="removeParticipant(participant)" class="remove-participant-btn">
                <i class="icon">🗑️</i>
                移除
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 参加比赛密码弹窗 -->
    <div v-if="showJoinDialog" class="modal-overlay" @click="closeJoinDialog">
      <div class="join-modal-content" @click.stop>
        <div class="join-modal-header">
          <h2>
            <i class="icon">🎯</i>
            参加比赛
          </h2>
          <button @click="closeJoinDialog" class="close-btn">✕</button>
        </div>
        
        <div class="join-modal-body">
          <div class="contest-info-box">
            <h3>{{ contestData.name || contestData.title }}</h3>
            <p class="contest-type-text">{{ contestData.type }}</p>
          </div>
          
          <div class="password-field">
            <label>
              <i class="icon">🔒</i>
              参赛密码
            </label>
            <input 
              v-model="joinPassword" 
              type="password" 
              placeholder="请输入参赛密码"
              class="password-input"
              @keyup.enter="confirmJoinContest"
            />
            <small class="hint">如果比赛无需密码，请直接点击确认</small>
          </div>
        </div>
        
        <div class="join-modal-footer">
          <button @click="closeJoinDialog" class="cancel-join-btn">取消</button>
          <button @click="confirmJoinContest" class="confirm-join-btn" :disabled="isJoining">
            {{ isJoining ? '报名中...' : '确认参加' }}
          </button>
        </div>
      </div>
    </div>
    
    <!-- 成绩表弹窗 -->
    <div v-if="showRankDialog" class="modal-overlay" @click="closeRankDialog">
      <div class="modal-content rank-modal-content" @click.stop>
        <div class="modal-header">
          <h2>
            <i class="icon">📊</i>
            比赛成绩排名
          </h2>
          <button @click="closeRankDialog" class="close-btn">✕</button>
        </div>
        
        <div class="modal-body">
          <!-- 比赛信息 -->
          <div v-if="rankData" class="rank-info-section">
            <div class="info-item">
              <span class="label">比赛名称：</span>
              <span class="value">{{ rankData.competitionName }}</span>
            </div>
            <div class="info-item">
              <span class="label">参赛人数：</span>
              <span class="value">{{ rankData.rankList ? rankData.rankList.length : 0 }} 人</span>
            </div>
          </div>
          
          <div v-if="!rankData || !rankData.rankList || rankData.rankList.length === 0" class="empty-rank">
            <i class="icon">📭</i>
            <p>暂无成绩数据</p>
          </div>
          
          <div v-else class="rank-table-wrapper">
            <table class="rank-table">
              <thead>
                <tr>
                  <th class="rank-header">排名</th>
                  <th class="name-header">用户</th>
                  <th class="score-header">分数</th>
                  <th class="time-header">总耗时</th>
                  <!-- 动态显示每道题目的表头 -->
                  <th v-for="(qScore, qIndex) in getQuestionHeaders()" 
                      :key="'q-header-' + qIndex" 
                      class="question-header">
                    {{ String.fromCharCode(65 + qIndex) }}
                  </th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(player, index) in rankData.rankList" :key="player.studentId || index" 
                    :class="getRowClass(player)">
                  <td class="rank-cell">
                    <span v-if="player.rank === 1" class="medal">🥇</span>
                    <span v-else-if="player.rank === 2" class="medal">🥈</span>
                    <span v-else-if="player.rank === 3" class="medal">🥉</span>
                    <span v-else-if="player.rank" class="rank-number">{{ player.rank }}</span>
                    <span v-else class="no-rank">-</span>
                  </td>
                  <td class="name-cell">
                    <div class="player-name">{{ player.studentName || player.userName || '未知' }}</div>
                  </td>
                  <td class="total-score-cell">
                    <div class="score-badge">{{ player.totalScore || 0 }}</div>
                  </td>
                  <td class="total-time-cell">
                    <div class="time-badge">{{ formatTimeShort(player.totalTime) }}</div>
                  </td>
                  <!-- 动态显示每道题的得分 -->
                  <td v-for="(qScore, qIndex) in getQuestionScores(player)" 
                      :key="'q-' + qIndex" 
                      class="question-cell">
                    <div v-if="qScore && qScore.score > 0" class="question-result">
                      <div class="score-green">{{ qScore.score }}</div>
                      <div v-if="qScore.timeSpent" class="time-green">{{ formatTimeSpent(qScore.timeSpent) }}</div>
                    </div>
                    <div v-else class="no-answer">-</div>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import logger from '../utils/logger.js'
import { getContestDetail, registerContest, getCompetitionPlayers, removeCompetitionPlayer, getContestRank } from '@/api/contest'

export default {
  name: 'ContestDetail',
  data() {
    return {
      isLoading: true,
      contestId: null,
      contestData: {},
      isManagementMode: false,  // 是否从比赛管理页面进入
      showParticipants: false,  // 是否显示选手列表弹窗
      participants: [],  // 选手列表
      showJoinDialog: false,  // 是否显示参加比赛弹窗
      joinPassword: '',  // 参赛密码
      isJoining: false,  // 是否正在报名
      hasJoined: false,  // 是否已参加比赛
      showRankDialog: false,  // 是否显示成绩表弹窗
      rankData: null  // 成绩排名数据
    }
  },
  computed: {
    // 判断当前用户是否为学生
    isStudent() {
      try {
        const token = localStorage.getItem('token')
        if (token) {
          const tokenParts = token.split('.')
          if (tokenParts.length === 3) {
            const payloadStr = atob(tokenParts[1])
            const roleMatch = payloadStr.match(/"role":(\d+)/)
            if (roleMatch && roleMatch[1]) {
              const role = parseInt(roleMatch[1])
              logger.log('👤 [ContestDetail] 当前用户角色:', role)
              return role === 3  // 3 = 学生
            }
          }
        }
        
        // 备选方案
        const userInfoStr = localStorage.getItem('userInfo')
        if (userInfoStr) {
          const userInfo = JSON.parse(userInfoStr)
          const role = typeof userInfo.role === 'string' ? parseInt(userInfo.role) : userInfo.role
          return role === 3
        }
      } catch (error) {
        logger.error('❌ [ContestDetail] 获取用户角色失败:', error)
      }
      
      return false
    }
  },
  
  mounted() {
    logger.log('👁️ [ContestDetail] 比赛详情页面已加载')
    this.contestId = this.$route.params.id
    
    // 判断是否从比赛管理页面进入
    this.isManagementMode = this.$route.query.from === 'management'
    logger.log('📝 [ContestDetail] 比赛ID:', this.contestId)
    logger.log('🔍 [ContestDetail] 是否管理模式:', this.isManagementMode)
    
    this.loadContestData()
  },
  
  methods: {
    // 加载比赛数据
    async loadContestData() {
      logger.log('📥 [ContestDetail] 开始加载比赛数据')
      this.isLoading = true
      
      try {
        logger.log('📞 [ContestDetail] 调用API获取比赛详情，ID:', this.contestId)
        
        // 调用API获取比赛详情
        const response = await getContestDetail(this.contestId)
        
        logger.log('✅ [ContestDetail] API响应:', response)
        
        // 检查业务状态码
        if (response && response.code === 0) {
          logger.log('✅ [ContestDetail] 比赛详情获取成功（code = 0）')
          
          if (response.data) {
            this.contestData = response.data
            
            // 检查当前用户是否已参加比赛
            this.checkJoinStatus()
            
            logger.log('📦 [ContestDetail] 比赛数据:', this.contestData)
          } else {
            logger.warn('⚠️ [ContestDetail] 后端返回的data为null，比赛不存在或已删除')
            
            if (this.$message && this.$message.warning) {
              this.$message.warning('该比赛不存在或已被删除')
            } else {
              alert('⚠️ 该比赛不存在或已被删除')
            }
            this.goBack()
          }
        } else {
          logger.error('❌ [ContestDetail] 获取详情失败:', response?.message)
          
          const errorMsg = response?.message || '加载比赛数据失败'
          if (this.$message && this.$message.error) {
            this.$message.error(errorMsg)
          } else {
            alert('❌ ' + errorMsg)
          }
          this.goBack()
        }
      } catch (error) {
        logger.error('❌ [ContestDetail] 加载比赛数据失败:', error)
        
        let errorMsg = '加载比赛数据失败'
        if (error.response?.data?.message) {
          errorMsg = error.response.data.message
        } else if (error.message) {
          errorMsg = error.message
        }
        
        if (this.$message && this.$message.error) {
          this.$message.error(errorMsg)
        } else {
          alert('❌ ' + errorMsg)
        }
        this.goBack()
      } finally {
        this.isLoading = false
      }
    },
    
    // 获取比赛类型样式
    getTypeClass(type) {
      const typeMap = {
        'ACM/ICPC比赛': 'type-acm',
        'OI比赛': 'type-oi',
        'IOI比赛': 'type-ioi',
        'Ledo 比赛': 'type-ledo',
        'IOI(Strict)比赛': 'type-ioi-strict'
      }
      return typeMap[type] || ''
    },
    
    // 获取状态样式
    getStatusClass(status) {
      const statusMap = {
        '未开始': 'status-pending',
        '进行中': 'status-active',
        '已结束': 'status-finished'
      }
      return statusMap[status] || ''
    },
    
    // 编辑比赛
    editContest() {
      logger.log('✏️ [ContestDetail] 跳转到编辑页面')
      this.$router.push({
        name: 'ContestEdit',
        params: { id: this.contestId }
      })
    },
    
    // 查看选手列表
    async viewParticipants() {
      logger.log('👥 [ContestDetail] 查看选手列表')
      
      try {
        logger.log('📞 [ContestDetail] 调用API获取选手列表，比赛ID:', this.contestId)
        
        // 调用API获取选手列表
        const response = await getCompetitionPlayers(this.contestId)
        
        logger.log('✅ [ContestDetail] API响应:', response)
        
        // 检查业务状态码
        if (response && response.code === 0) {
          logger.log('✅ [ContestDetail] 选手列表获取成功（code = 0）')
          
          // 更新选手列表数据
          // 后端返回的是分页数据结构：{ records: [...], total: 2, size: 10, current: 1, pages: 1 }
          if (response.data && Array.isArray(response.data)) {
            // 如果data直接是数组
            this.participants = response.data
            logger.log('📋 [ContestDetail] 选手数量:', this.participants.length)
            logger.log('📦 [ContestDetail] 选手列表数据:', this.participants)
          } else if (response.data && Array.isArray(response.data.records)) {
            // 如果是分页数据结构，从records中获取
            this.participants = response.data.records
            logger.log('📋 [ContestDetail] 从records获取选手数量:', this.participants.length)
            logger.log('📊 [ContestDetail] 总数:', response.data.total)
            logger.log('📦 [ContestDetail] 选手列表数据:', this.participants)
          } else {
            // 备用：尝试从registrants字段获取
            this.participants = response.data?.registrants || []
            logger.log('📋 [ContestDetail] 从registrants获取选手数量:', this.participants.length)
          }
          
          // 显示选手列表弹窗
          this.showParticipants = true
        } else {
          logger.error('❌ [ContestDetail] 获取选手列表失败:', response?.message)
          
          const errorMsg = response?.message || '获取选手列表失败'
          if (this.$message && this.$message.error) {
            this.$message.error(errorMsg)
          } else {
            alert('❌ ' + errorMsg)
          }
          
          // 使用备用数据
          this.participants = this.contestData.registrants || []
          this.showParticipants = true
        }
      } catch (error) {
        logger.error('❌ [ContestDetail] 获取选手列表失败:', error)
        
        let errorMsg = '获取选手列表失败'
        if (error.response?.data?.message) {
          errorMsg = error.response.data.message
        } else if (error.message) {
          errorMsg = error.message
        }
        
        if (this.$message && this.$message.error) {
          this.$message.error(errorMsg)
        } else {
          alert('❌ ' + errorMsg)
        }
        
        // 使用备用数据
        this.participants = this.contestData.registrants || []
        this.showParticipants = true
      }
    },
    
    // 关闭选手列表弹窗
    closeParticipants() {
      logger.log('✕ [ContestDetail] 关闭选手列表')
      this.showParticipants = false
    },
    
    // 删除选手（移除选手）
    async removeParticipant(participant) {
      logger.log('🗑️ [ContestDetail] 移除选手:', participant)
      
      const participantName = participant.userName || participant.name || participant.username || '该选手'
      const confirmed = confirm(`确定要移除选手"${participantName}"吗？`)
      
      if (!confirmed) {
        logger.log('❌ [ContestDetail] 用户取消移除')
        return
      }
      
      try {
        logger.log('🔥 [ContestDetail] 执行移除操作')
        logger.log('🆔 [ContestDetail] 比赛ID:', this.contestId)
        logger.log('🆔 [ContestDetail] 比赛ID类型:', typeof this.contestId)
        logger.log('👤 [ContestDetail] 用户ID:', participant.userId)
        logger.log('👤 [ContestDetail] 用户ID类型:', typeof participant.userId)
        logger.log('👤 [ContestDetail] 用户ID长度:', String(participant.userId).length, '位')
        
        // 调用API移除选手
        const response = await removeCompetitionPlayer(this.contestId, participant.userId)
        
        logger.log('✅ [ContestDetail] API响应:', response)
        
        // 检查业务状态码
        if (response && response.code === 0) {
          logger.log('✅ [ContestDetail] 选手移除成功（code = 0）')
          
          // 从列表中移除该选手
          this.participants = this.participants.filter(p => p.id !== participant.id)
          
          // 移除成功提示，直接更新列表以改善用户体验
          // const successMsg = response.message || '选手已移除'
          // if (this.$message && this.$message.success) {
          //   this.$message.success(successMsg)
          // } else {
          //   alert('✅ ' + successMsg)
          // }
          
          logger.log('✅ [ContestDetail] 前端列表已更新')
        } else {
          logger.error('❌ [ContestDetail] 移除选手失败，业务状态码异常')
          logger.error('❌ [ContestDetail] code:', response?.code)
          logger.error('❌ [ContestDetail] message:', response?.message)
          
          const errorMsg = response?.message || '移除选手失败'
          if (this.$message && this.$message.error) {
            this.$message.error(errorMsg)
          } else {
            alert('❌ ' + errorMsg)
          }
        }
      } catch (error) {
        logger.error('❌ [ContestDetail] 移除选手失败:', error)
        
        let errorMsg = '移除选手失败，请重试'
        if (error.response?.data?.message) {
          errorMsg = error.response.data.message
        } else if (error.message) {
          errorMsg = error.message
        }
        
        if (this.$message && this.$message.error) {
          this.$message.error(errorMsg)
        } else {
          alert('❌ ' + errorMsg)
        }
      }
    },
    
    // 检查当前用户是否已参加比赛
    checkJoinStatus() {
      try {
        const userId = this.getCurrentUserId()
        if (!userId) {
          this.hasJoined = false
          return
        }
        
        // 检查registrants列表中是否包含当前用户
        if (this.contestData.registrants && Array.isArray(this.contestData.registrants)) {
          this.hasJoined = this.contestData.registrants.some(participant => {
            const participantId = String(participant.userId || participant.id || '')
            return participantId === userId
          })
        } else {
          this.hasJoined = false
        }
        
        logger.log('✅ [ContestDetail] 参赛状态检查:', this.hasJoined ? '已参加' : '未参加')
      } catch (error) {
        logger.error('❌ [ContestDetail] 检查参赛状态失败:', error)
        this.hasJoined = false
      }
    },
    
    // 进入答题页面（已参加的用户）
    enterExam() {
      logger.log('📝 [ContestDetail] 进入答题页面')
      this.$router.push({
        name: 'ContestExam',
        params: { id: this.contestId }
      })
    },
    
    // 获取头像文字
    getAvatarText(name) {
      if (!name) return 'U'
      return name.charAt(0).toUpperCase()
    },
    
    // 格式化日期
    formatDate(dateStr) {
      if (!dateStr) return '未知'
      try {
        const date = new Date(dateStr)
        if (isNaN(date.getTime())) return dateStr
        
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        const hours = String(date.getHours()).padStart(2, '0')
        const minutes = String(date.getMinutes()).padStart(2, '0')
        
        return `${year}-${month}-${day} ${hours}:${minutes}`
      } catch (error) {
        logger.error('❌ [ContestDetail] 日期格式化失败:', error)
        return dateStr
      }
    },
    
    // 格式化时间（毫秒转为可读格式）
    formatTime(milliseconds) {
      if (!milliseconds || milliseconds === 0) return '-'
      
      const seconds = Math.floor(milliseconds / 1000)
      const minutes = Math.floor(seconds / 60)
      const hours = Math.floor(minutes / 60)
      
      if (hours > 0) {
        return `${hours}小时${minutes % 60}分`
      } else if (minutes > 0) {
        return `${minutes}分${seconds % 60}秒`
      } else {
        return `${seconds}秒`
      }
    },
    
    // 检查是否有题目得分数据
    hasQuestionScores() {
      if (!this.rankData || !this.rankData.rankList) {
        return false
      }
      
      // 检查是否有任何选手有题目得分
      return this.rankData.rankList.some(player => 
        player.questionScores && player.questionScores.length > 0
      )
    },
    
    // 获取题目数量（用于动态生成表头）
    getQuestionHeaders() {
      if (!this.rankData || !this.rankData.rankList) {
        return []
      }
      
      // 找到题目最多的选手
      let maxQuestions = 0
      this.rankData.rankList.forEach(player => {
        if (player.questionScores && player.questionScores.length > maxQuestions) {
          maxQuestions = player.questionScores.length
        }
      })
      
      // 返回一个数组，长度为题目数量
      return Array(maxQuestions).fill(0)
    },
    
    // 获取选手的每道题得分（按题目顺序）
    getQuestionScores(player) {
      if (!player.questionScores || player.questionScores.length === 0) {
        // 返回空数组，长度为题目总数
        const questionCount = this.getQuestionHeaders().length
        return Array(questionCount).fill(null)
      }
      
      return player.questionScores
    },
    
    // 获取行样式类
    getRowClass(player) {
      const classes = []
      
      // 前三名高亮
      if (player.rank >= 1 && player.rank <= 3) {
        classes.push('top-rank')
      }
      
      // 未提交的行
      if (player.totalScore === 0 || !player.submitTime) {
        classes.push('no-submit')
      }
      
      return classes.join(' ')
    },
    
    // 格式化时间（短格式）
    formatTimeShort(milliseconds) {
      if (!milliseconds || milliseconds === 0) return '0:00'
      
      const totalSeconds = Math.floor(milliseconds / 1000)
      const minutes = Math.floor(totalSeconds / 60)
      const seconds = totalSeconds % 60
      
      return `${minutes}:${String(seconds).padStart(2, '0')}`
    },
    
    // 格式化题目耗时
    formatTimeSpent(milliseconds) {
      if (!milliseconds || milliseconds === 0) return ''
      
      const totalSeconds = Math.floor(milliseconds / 1000)
      const minutes = Math.floor(totalSeconds / 60)
      const seconds = totalSeconds % 60
      
      if (minutes > 0) {
        return `${minutes}:${String(seconds).padStart(2, '0')}`
      } else {
        return `0:${String(seconds).padStart(2, '0')}`
      }
    },
    
    // 查看成绩表
    async viewRankings() {
      logger.log('📊 [ContestDetail] 查看成绩表')
      
      try {
        logger.log('📞 [ContestDetail] 调用API获取比赛排名，比赛ID:', this.contestId)
        
        // 调用API获取比赛排名
        const response = await getContestRank(this.contestId)
        
        logger.log('✅ [ContestDetail] API响应:', response)
        
        // 检查业务状态码
        if (response && response.code === 0) {
          logger.log('✅ [ContestDetail] 比赛排名获取成功（code = 0）')
          
          // 更新排名数据
          this.rankData = response.data
          
          // 🔥 前端对排名进行排序
          if (this.rankData && this.rankData.rankList && Array.isArray(this.rankData.rankList)) {
            logger.log('📊 [ContestDetail] 开始对成绩进行排序...')
            logger.log('📊 [ContestDetail] 排序前的数据:', this.rankData.rankList)
            
            // 排序规则：
            // 1. 总分高的排前面
            // 2. 总分相同时，耗时短的排前面
            this.rankData.rankList.sort((a, b) => {
              // 首先按总分降序排列（分数高的在前）
              if (b.totalScore !== a.totalScore) {
                return b.totalScore - a.totalScore
              }
              
              // 总分相同时，按耗时升序排列（时间短的在前）
              // 注意：未提交的选手（totalScore=0）耗时也为0，需要特殊处理
              if (a.totalScore === 0) {
                // 两个都未提交，保持原顺序
                return 0
              }
              
              // 都提交了且分数相同，比较耗时
              return a.totalTime - b.totalTime
            })
            
            // 重新计算排名
            let currentRank = 1
            for (let i = 0; i < this.rankData.rankList.length; i++) {
              const player = this.rankData.rankList[i]
              
              // 未提交的不显示排名
              if (player.totalScore === 0) {
                player.rank = null
                continue
              }
              
              // 如果不是第一个，检查是否与前一个成绩相同
              if (i > 0) {
                const prevPlayer = this.rankData.rankList[i - 1]
                
                // 如果总分和耗时都相同，排名相同
                if (player.totalScore === prevPlayer.totalScore && 
                    player.totalTime === prevPlayer.totalTime) {
                  player.rank = prevPlayer.rank
                } else {
                  // 否则排名为当前位置
                  currentRank = i + 1
                  player.rank = currentRank
                }
              } else {
                // 第一个选手
                player.rank = 1
              }
            }
            
            logger.log('📊 [ContestDetail] 排序后的数据:', this.rankData.rankList)
            logger.log('📊 [ContestDetail] 排名详情:')
            this.rankData.rankList.forEach((player, index) => {
              logger.log(`  ${player.rank || '-'}. ${player.studentName} - 总分: ${player.totalScore}, 耗时: ${player.totalTime}ms`)
            })
          }
          
          logger.log('📦 [ContestDetail] 排名数据:', this.rankData)
          
          // 显示成绩表弹窗
          this.showRankDialog = true
        } else {
          logger.error('❌ [ContestDetail] 获取比赛排名失败:', response?.message)
          
          const errorMsg = response?.message || '获取比赛排名失败'
          if (this.$message && this.$message.error) {
            this.$message.error(errorMsg)
          } else {
            alert('❌ ' + errorMsg)
          }
        }
      } catch (error) {
        logger.error('❌ [ContestDetail] 获取比赛排名失败:', error)
        
        let errorMsg = '获取比赛排名失败'
        if (error.response?.data?.message) {
          errorMsg = error.response.data.message
        } else if (error.message) {
          errorMsg = error.message
        }
        
        if (this.$message && this.$message.error) {
          this.$message.error(errorMsg)
        } else {
          alert('❌ ' + errorMsg)
        }
      }
    },
    
    // 关闭成绩表弹窗
    closeRankDialog() {
      logger.log('✕ [ContestDetail] 关闭成绩表')
      this.showRankDialog = false
    },
    
    // 参加比赛 - 打开密码弹窗
    joinContest() {
      logger.log('🎯 [ContestDetail] 打开参加比赛弹窗')
      this.joinPassword = ''
      this.showJoinDialog = true
    },
    
    // 关闭参加比赛弹窗
    closeJoinDialog() {
      logger.log('✕ [ContestDetail] 关闭参加比赛弹窗')
      this.showJoinDialog = false
      this.joinPassword = ''
      this.isJoining = false
    },
    
    // 获取当前用户ID（保持19位精度）
    getCurrentUserId() {
      try {
        const token = localStorage.getItem('token')
        if (token) {
          const tokenParts = token.split('.')
          if (tokenParts.length === 3) {
            const payloadBase64 = tokenParts[1]
            const payloadStr = atob(payloadBase64)
            const idMatch = payloadStr.match(/"id":(\d+)/)
            if (idMatch && idMatch[1]) {
              const userId = idMatch[1]
              logger.log('👤 [ContestDetail] 从JWT令牌获取用户ID:', userId)
              logger.log('👤 [ContestDetail] 用户ID长度:', userId.length, '位')
              return userId
            }
          }
        }
        
        const userInfoStr = localStorage.getItem('userInfo')
        if (userInfoStr) {
          const userInfo = JSON.parse(userInfoStr)
          const userId = String(userInfo.id || '')
          logger.log('👤 [ContestDetail] 从localStorage获取用户ID:', userId)
          return userId
        }
      } catch (error) {
        logger.error('❌ [ContestDetail] 解析用户信息失败:', error)
      }
      
      logger.warn('⚠️ [ContestDetail] 无法获取用户ID')
      return null
    },
    
    // 确认参加比赛
    async confirmJoinContest() {
      logger.log('✅ [ContestDetail] 确认参加比赛')
      
      this.isJoining = true
      
      try {
        // 获取用户ID
        const userId = this.getCurrentUserId()
        if (!userId) {
          if (this.$message && this.$message.error) {
            this.$message.error('获取用户信息失败，请重新登录')
          } else {
            alert('❌ 获取用户信息失败，请重新登录')
          }
          this.isJoining = false
          return
        }
        
        // 构建报名数据
        const registerData = {
          competitionId: String(this.contestId),  // 比赛ID（字符串格式，后端转long）
          userId: userId,  // 用户ID（字符串格式，后端转long）
          password: this.joinPassword || ''  // 密码（可选）
        }
        
        logger.log('📝 [ContestDetail] 报名数据:', registerData)
        logger.log('🆔 [ContestDetail] 比赛ID:', registerData.competitionId, '类型:', typeof registerData.competitionId)
        logger.log('👤 [ContestDetail] 用户ID:', registerData.userId, '类型:', typeof registerData.userId)
        
        // 调用API
        const response = await registerContest(registerData)
        
        logger.log('✅ [ContestDetail] API响应:', response)
        
        // 检查业务状态码
        if (response && response.code === 0) {
          logger.log('✅ [ContestDetail] 参加比赛成功（code = 0）')
          
          // 移除成功提示，直接跳转以改善用户体验
          // const successMsg = response.message || '报名成功！'
          // if (this.$message && this.$message.success) {
          //   this.$message.success(successMsg)
          // } else {
          //   alert('✅ ' + successMsg)
          // }
          
          // 关闭弹窗
          this.closeJoinDialog()
          
          // 标记为已参加
          this.hasJoined = true
          
          // 跳转到比赛做题页面
          logger.log('🚀 [ContestDetail] 跳转到比赛做题页面')
          this.$router.push({
            name: 'ContestExam',
            params: { id: this.contestId }
          })
        } else {
          logger.error('❌ [ContestDetail] 参加比赛失败，业务状态码异常')
          logger.error('❌ [ContestDetail] code:', response?.code)
          logger.error('❌ [ContestDetail] message:', response?.message)
          
          const errorMsg = response?.message || '参加比赛失败'
          if (this.$message && this.$message.error) {
            this.$message.error(errorMsg)
          } else {
            alert('❌ ' + errorMsg)
          }
        }
      } catch (error) {
        logger.error('❌ [ContestDetail] 参加比赛失败:', error)
        
        let errorMsg = '参加比赛失败，请重试'
        if (error.response?.data?.message) {
          errorMsg = error.response.data.message
        } else if (error.message) {
          errorMsg = error.message
        }
        
        if (this.$message && this.$message.error) {
          this.$message.error(errorMsg)
        } else {
          alert('❌ ' + errorMsg)
        }
      } finally {
        this.isJoining = false
      }
    },
    
    // 返回上一页
    goBack() {
      if (this.isManagementMode) {
        this.$router.push('/contest-management')
      } else {
        this.$router.push('/contests')
      }
    }
  }
}
</script>

<style scoped>
.contest-detail-page {
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 30px 20px;
}

/* 页面头部 */
.page-header {
  margin-bottom: 30px;
  animation: fadeInDown 0.6s ease;
}

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translateY(-30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.header-content {
  max-width: 1200px;
  margin: 0 auto;
  background: rgba(255, 255, 255, 0.98);
  padding: 30px 40px;
  border-radius: 20px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(10px);
}

.back-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px;
  background: #6c757d;
  color: white;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  transition: all 0.3s ease;
  margin-bottom: 20px;
}

.back-btn:hover {
  background: #5a6268;
  transform: translateX(-3px);
}

.back-btn .icon {
  font-size: 16px;
}

.header-info {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  width: 100%;
  gap: 20px;
}

.title-section {
  flex: 1;
}

.page-title {
  font-size: 2em;
  margin: 0 0 12px 0;
  color: #2c3e50;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 12px;
}

.page-title .icon {
  font-size: 1.2em;
}

.header-badges {
  display: flex;
  gap: 10px;
}

/* 右上角按钮组 */
.header-actions {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.header-action-btn {
  padding: 12px 24px;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  font-size: 15px;
  font-weight: 600;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

.header-action-btn .icon {
  font-size: 18px;
}

.rankings-btn {
  background: linear-gradient(135deg, #e3f2fd, #90caf9);
  color: #1976d2;
  border: 2px solid #64b5f6;
  box-shadow: 0 4px 15px rgba(25, 118, 210, 0.2);
}

.rankings-btn:hover {
  background: linear-gradient(135deg, #1976d2, #1565c0);
  color: white;
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(25, 118, 210, 0.4);
}

.join-btn {
  background: linear-gradient(135deg, #4CAF50, #45a049);
  color: white;
  box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
}

.join-btn:hover {
  background: linear-gradient(135deg, #388e3c, #2e7d32);
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(76, 175, 80, 0.5);
}

.entered-btn {
  background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
  color: #2e7d32;
  border: 2px solid #66bb6a;
  box-shadow: 0 4px 15px rgba(76, 175, 80, 0.2);
}

.entered-btn:hover {
  background: linear-gradient(135deg, #4CAF50, #45a049);
  color: white;
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);
}

.participants-btn {
  background: linear-gradient(135deg, #f3e5f5, #ce93d8);
  color: #7b1fa2;
  border: 2px solid #ba68c8;
  box-shadow: 0 4px 15px rgba(123, 31, 162, 0.2);
}

.participants-btn:hover {
  background: linear-gradient(135deg, #7b1fa2, #6a1b9a);
  color: white;
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(123, 31, 162, 0.4);
}

.badge {
  padding: 8px 16px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.5px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 比赛类型样式 */
.type-acm {
  background: #e3f2fd;
  color: #1976d2;
}

.type-oi {
  background: #f3e5f5;
  color: #7b1fa2;
}

.type-ioi {
  background: #e8f5e9;
  color: #388e3c;
}

.type-ledo {
  background: #fff3e0;
  color: #f57c00;
}

.type-ioi-strict {
  background: #fce4ec;
  color: #c2185b;
}

/* 状态样式 */
.status-pending {
  background: #fff3e0;
  color: #f57c00;
}

.status-active {
  background: #e8f5e9;
  color: #388e3c;
}

.status-finished {
  background: #e0e0e0;
  color: #616161;
}

/* 加载状态 */
.loading-container {
  max-width: 1200px;
  margin: 0 auto;
  text-align: center;
  padding: 100px 20px;
  background: rgba(255, 255, 255, 0.98);
  border-radius: 20px;
}

.loading-spinner {
  width: 60px;
  height: 60px;
  margin: 0 auto 25px;
  border: 5px solid #f3f3f3;
  border-top: 5px solid #667eea;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.loading-container p {
  color: #7f8c8d;
  font-size: 18px;
  font-weight: 500;
}

/* 内容区域 */
.content-wrapper {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 25px;
  animation: fadeInUp 0.6s ease;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 信息卡片 */
.info-card {
  background: rgba(255, 255, 255, 0.98);
  border-radius: 20px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
  overflow: hidden;
  transition: all 0.3s ease;
}

.info-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}

.card-header {
  background: linear-gradient(135deg, #667eea, #764ba2);
  padding: 20px 30px;
  color: white;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-header h3 {
  margin: 0;
  font-size: 1.3em;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 10px;
}

.card-header .icon {
  font-size: 1.2em;
}

.question-count {
  background: rgba(255, 255, 255, 0.2);
  padding: 6px 14px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 600;
}

.card-content {
  padding: 30px;
}

/* 信息网格 */
.info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 25px;
}

.info-item {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.info-item.full-width {
  grid-column: 1 / -1;
}

.info-item label {
  font-size: 13px;
  color: #7f8c8d;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.info-value {
  font-size: 16px;
  color: #2c3e50;
  font-weight: 500;
  padding: 12px 16px;
  background: #f8f9fa;
  border-radius: 10px;
  border-left: 4px solid #667eea;
}

.info-value.description {
  line-height: 1.6;
  white-space: pre-wrap;
}

.info-value.time-value {
  display: flex;
  align-items: center;
  gap: 8px;
}

.stat-number {
  font-size: 24px;
  font-weight: 700;
  color: #667eea;
  margin-right: 5px;
}

/* 题目表格 */
.questions-table-wrapper {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.questions-table {
  width: 100%;
  border-collapse: collapse;
}

.questions-table th {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  padding: 15px;
  text-align: left;
  font-weight: 600;
  font-size: 14px;
}

.questions-table td {
  padding: 15px;
  border-bottom: 1px solid #e9ecef;
  font-size: 14px;
}

.questions-table tr:last-child td {
  border-bottom: none;
}

.questions-table tr:hover {
  background: #f8f9fa;
}

.title-cell {
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  color: #2c3e50;
}

.score-cell {
  text-align: center;
}

.score-badge {
  display: inline-block;
  padding: 6px 14px;
  background: linear-gradient(135deg, #4CAF50, #45a049);
  color: white;
  border-radius: 20px;
  font-weight: 600;
  font-size: 13px;
}

.no-questions {
  text-align: center;
  padding: 60px 20px;
  color: #7f8c8d;
}

.no-questions .icon {
  font-size: 60px;
  margin-bottom: 15px;
  display: block;
}

.no-questions p {
  font-size: 16px;
  margin: 0;
}

/* 操作按钮 */
.action-buttons {
  display: flex;
  justify-content: center;
  gap: 15px;
  padding: 30px;
  background: rgba(255, 255, 255, 0.98);
  border-radius: 20px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}

.btn {
  padding: 14px 35px;
  border: none;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 8px;
}

.btn .icon {
  font-size: 16px;
}

.btn-primary {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}

.btn-primary:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}

.btn-secondary {
  background: #6c757d;
  color: white;
  box-shadow: 0 4px 15px rgba(108, 117, 125, 0.3);
}

.btn-secondary:hover {
  background: #5a6268;
  transform: translateY(-3px);
  box-shadow: 0 6px 20px rgba(108, 117, 125, 0.4);
}

/* 选手列表弹窗 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
  animation: fadeIn 0.3s ease;
}

.modal-content {
  background: white;
  border-radius: 20px;
  width: 90%;
  max-width: 900px;
  max-height: 85vh;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  animation: slideUp 0.3s ease;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(50px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.modal-header {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  padding: 25px 30px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-header h2 {
  margin: 0;
  font-size: 1.5em;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 10px;
}

.close-btn {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  color: white;
  width: 35px;
  height: 35px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

.close-btn:hover {
  background: rgba(255, 255, 255, 0.3);
  transform: rotate(90deg);
}

.modal-body {
  padding: 30px;
  max-height: calc(85vh - 100px);
  overflow-y: auto;
}

/* 空状态 */
.empty-participants {
  text-align: center;
  padding: 80px 20px;
  color: #7f8c8d;
}

.empty-participants .icon {
  font-size: 80px;
  margin-bottom: 20px;
  display: block;
}

.empty-participants p {
  font-size: 18px;
  margin: 0;
}

/* 选手卡片网格 */
.participants-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
}

.participant-card {
  background: #f8f9fa;
  border-radius: 15px;
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 15px;
  transition: all 0.3s ease;
  border: 2px solid transparent;
  position: relative;
}

.participant-card:hover {
  background: white;
  border-color: #667eea;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
  transform: translateY(-3px);
}

.participant-avatar {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
}

.participant-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-placeholder {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  font-weight: 700;
}

.participant-info {
  flex: 1;
  min-width: 0;
}

.participant-name {
  margin: 0 0 5px 0;
  font-size: 16px;
  font-weight: 600;
  color: #2c3e50;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.participant-email {
  margin: 0 0 8px 0;
  font-size: 13px;
  color: #7f8c8d;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.participant-meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.meta-tag {
  font-size: 12px;
  color: #6c757d;
  background: rgba(102, 126, 234, 0.1);
  padding: 4px 10px;
  border-radius: 12px;
}

.remove-participant-btn {
  padding: 8px 16px;
  background: linear-gradient(135deg, #ffebee, #ffcdd2);
  color: #d32f2f;
  border: 1px solid #ef9a9a;
  border-radius: 10px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 5px;
  transition: all 0.3s ease;
  flex-shrink: 0;
}

.remove-participant-btn:hover {
  background: linear-gradient(135deg, #d32f2f, #c62828);
  color: white;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(211, 47, 47, 0.3);
}

.remove-participant-btn .icon {
  font-size: 14px;
}

/* 参加比赛弹窗样式 */
.join-modal-content {
  background: white;
  border-radius: 20px;
  width: 90%;
  max-width: 500px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  animation: slideUp 0.3s ease;
}

.join-modal-header {
  background: linear-gradient(135deg, #4CAF50, #45a049);
  color: white;
  padding: 25px 30px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.join-modal-header h2 {
  margin: 0;
  font-size: 1.5em;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 10px;
}

.join-modal-body {
  padding: 30px;
}

.contest-info-box {
  background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
  padding: 20px;
  border-radius: 12px;
  margin-bottom: 25px;
  text-align: center;
}

.contest-info-box h3 {
  margin: 0 0 10px 0;
  font-size: 1.3em;
  color: #2c3e50;
  font-weight: 700;
}

.contest-type-text {
  margin: 0;
  font-size: 14px;
  color: #388e3c;
  font-weight: 600;
}

.password-field {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.password-field label {
  font-size: 14px;
  color: #2c3e50;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}

.password-input {
  width: 100%;
  padding: 14px 18px;
  border: 2px solid #dee2e6;
  border-radius: 10px;
  font-size: 15px;
  transition: all 0.3s ease;
  box-sizing: border-box;
}

.password-input:focus {
  outline: none;
  border-color: #4CAF50;
  box-shadow: 0 0 0 4px rgba(76, 175, 80, 0.1);
}

.password-field .hint {
  font-size: 12px;
  color: #7f8c8d;
  font-style: italic;
}

.join-modal-footer {
  padding: 20px 30px;
  background: #f8f9fa;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.cancel-join-btn,
.confirm-join-btn {
  padding: 12px 28px;
  border: none;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.cancel-join-btn {
  background: #6c757d;
  color: white;
}

.cancel-join-btn:hover {
  background: #5a6268;
  transform: translateY(-2px);
}

.confirm-join-btn {
  background: linear-gradient(135deg, #4CAF50, #45a049);
  color: white;
  box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
}

.confirm-join-btn:hover:not(:disabled) {
  background: linear-gradient(135deg, #388e3c, #2e7d32);
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(76, 175, 80, 0.4);
}

.confirm-join-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* 成绩表弹窗样式 */
.rank-modal-content {
  max-width: 1200px;
}

.rank-info-section {
  background: linear-gradient(135deg, #e3f2fd, #f8f9fa);
  padding: 20px;
  border-radius: 12px;
  margin-bottom: 20px;
  display: flex;
  gap: 30px;
}

.rank-info-section .info-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.rank-info-section .label {
  font-weight: 600;
  color: #666;
}

.rank-info-section .value {
  font-weight: 700;
  color: #2c3e50;
  font-size: 16px;
}

.empty-rank {
  text-align: center;
  padding: 80px 20px;
  color: #7f8c8d;
}

.empty-rank .icon {
  font-size: 80px;
  margin-bottom: 20px;
  display: block;
}

.empty-rank p {
  font-size: 18px;
  margin: 0;
}

.rank-table-wrapper {
  overflow-x: auto;
}

.rank-table {
  width: 100%;
  border-collapse: collapse;
  background: white;
  font-size: 14px;
}

.rank-table thead {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
}

.rank-table th {
  padding: 12px 10px;
  text-align: center;
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
}

.rank-table th:last-child {
  border-right: none;
}

.rank-header {
  width: 60px;
}

.name-header {
  text-align: left !important;
  min-width: 120px;
}

.score-header,
.time-header {
  width: 100px;
}

.question-header {
  width: 80px;
  font-size: 14px;
  font-weight: 700;
}

.rank-table td {
  padding: 12px 10px;
  border-bottom: 1px solid #e9ecef;
  text-align: center;
  vertical-align: middle;
}

.rank-table tr:last-child td {
  border-bottom: none;
}

.rank-table tr:hover {
  background: #f8f9fa;
}

.rank-table tr.top-rank {
  background: linear-gradient(135deg, #fff9e6, #fffbf0);
}

.rank-table tr.top-rank:hover {
  background: linear-gradient(135deg, #fff3cd, #fff9e6);
}

.rank-table tr.no-submit {
  opacity: 0.6;
  background: #fafafa;
}

.rank-cell {
  text-align: center;
}

.medal {
  font-size: 22px;
}

.rank-number {
  font-size: 16px;
  font-weight: 700;
  color: #667eea;
}

.no-rank {
  color: #bdc3c7;
  font-size: 14px;
}

.name-cell {
  text-align: left !important;
}

.player-name {
  font-weight: 600;
  color: #2c3e50;
  font-size: 14px;
}

.total-score-cell,
.total-time-cell {
  text-align: center;
}

.score-badge {
  display: inline-block;
  font-weight: 700;
  color: #2c3e50;
  font-size: 16px;
}

.time-badge {
  color: #667eea;
  font-weight: 500;
  font-size: 14px;
}

.question-cell {
  padding: 8px 10px !important;
  text-align: center;
}

.question-result {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.score-green {
  color: #4CAF50;
  font-weight: 700;
  font-size: 15px;
}

.time-green {
  color: #4CAF50;
  font-weight: 500;
  font-size: 12px;
}

.no-answer {
  color: #bdc3c7;
  font-size: 14px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .rank-info-section {
    flex-direction: column;
    gap: 15px;
  }
  
  .rank-table {
    font-size: 12px;
  }
  
  .rank-table th,
  .rank-table td {
    padding: 8px 6px;
  }
  
  .question-header {
    width: 60px;
  }
  
  .score-green,
  .time-green {
    font-size: 12px;
  }
  
  .contest-detail-page {
    padding: 15px 10px;
  }
  
  .header-content {
    padding: 25px;
  }
  
  .header-info {
    flex-direction: column;
    gap: 15px;
  }
  
  .page-title {
    font-size: 1.5em;
  }
  
  .header-badges {
    align-self: flex-start;
  }
  
  .header-actions {
    width: 100%;
    flex-direction: column;
  }
  
  .header-action-btn {
    width: 100%;
    justify-content: center;
  }
  
  .info-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  
  .card-content {
    padding: 20px;
  }
  
  .action-buttons {
    flex-direction: column;
  }
  
  .btn {
    width: 100%;
    justify-content: center;
  }
  
  .questions-table {
    font-size: 12px;
  }
  
  .questions-table th,
  .questions-table td {
    padding: 10px 8px;
  }
  
  .modal-content {
    width: 95%;
    max-height: 90vh;
  }
  
  .modal-body {
    padding: 20px;
  }
  
  .participants-grid {
    grid-template-columns: 1fr;
  }
  
  .participant-card {
    flex-direction: column;
    text-align: center;
  }
  
  .participant-info {
    text-align: center;
  }
  
  .remove-participant-btn {
    width: 100%;
    justify-content: center;
  }
}
</style>

